route.ts 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. import { NextRequest, NextResponse } from 'next/server';
  2. import { getAccessToken } from '@/lib/utils/server';
  3. const API_URL = process.env.API_URL;
  4. export async function GET(_: NextRequest, { params }: { params: Promise<{ uuid: string }> })
  5. {
  6. const { uuid } = await params;
  7. try {
  8. const accessToken = await getAccessToken();
  9. // 백엔드에서 파일 메타데이터(url, fileName) 조회 + 권한 체크
  10. const res = await fetch(`${API_URL}/api/forum/comment/file/${uuid}`, {
  11. cache: 'no-store',
  12. headers: {
  13. ...(accessToken ? { 'Authorization': `Bearer ${accessToken}` } : {})
  14. }
  15. });
  16. if (!res.ok) {
  17. return new NextResponse(null, {
  18. status: res.status
  19. });
  20. }
  21. const json = await res.json();
  22. const fileUrl = json?.data?.url;
  23. const fileName = json?.data?.fileName;
  24. if (!fileUrl) {
  25. return new NextResponse(null, { status: 404 });
  26. }
  27. // 실제 파일 다운로드 (백엔드 서버에서)
  28. const fileRes = await fetch(`${API_URL}${fileUrl}`, {
  29. cache: 'no-store'
  30. });
  31. if (!fileRes.ok) {
  32. return new NextResponse(null, {
  33. status: fileRes.status
  34. });
  35. }
  36. const contentType = fileRes.headers.get('content-type') || 'application/octet-stream';
  37. const buffer = await fileRes.arrayBuffer();
  38. const encodedFileName = encodeURIComponent(fileName || 'download');
  39. return new NextResponse(buffer, {
  40. status: 200,
  41. headers: {
  42. 'Content-Type': contentType,
  43. 'Content-Disposition': `attachment; filename*=UTF-8''${encodedFileName}`
  44. }
  45. });
  46. } catch {
  47. return new NextResponse(null, {
  48. status: 502
  49. });
  50. }
  51. }